#include "GLTextureMVP3DWindow.h"

GLTextureMVP3DWindow::GLTextureMVP3DWindow(QWidget* parent)
	: BaseOpenGLWindow(parent)
{
	this->setWindowTitle("平面纹理MVP矩阵测试（Model->View->Projection）");
	this->resize(480, 800);
	QVBoxLayout* vBoxLayout = new QVBoxLayout(this);
	QHBoxLayout* hLayoutModel = new QHBoxLayout(this);
	QRadioButton* modelRbX = new QRadioButton(this);
	modelRbX->setText("X");
	QRadioButton* modelRbY = new QRadioButton(this);
	modelRbY->setText("Y");
	QRadioButton* modelRbZ = new QRadioButton(this);
	modelRbZ->setText("Z");
	SeekBarTipsWidget* modelSeekBar = new SeekBarTipsWidget(this);
	modelSeekBar->initContent(-360, 360, 10, "Model矩阵参数调整",
		[=](int value) {
			mRotateAngle = (float)value;
			uModelMatrix.rotate(mRotateAngle, QVector3D(mRoateX, mRoateY, mRoateZ));//设置model矩阵（旋转）
			update();
		});
	connect(modelRbX, &QPushButton::clicked, [this]() {
		mRoateX = 1.0f;
		mRoateY = 0.0f;
		mRoateZ = 0.0f;
		});
	connect(modelRbY, &QPushButton::clicked, [this]() {
		mRoateX = 0.0f;
		mRoateY = 1.0f;
		mRoateZ = 0.0f;
		});
	connect(modelRbZ, &QPushButton::clicked, [this]() {
		mRoateX = 0.0f;
		mRoateY = 0.0f;
		mRoateZ = 1.0f;
		});
	hLayoutModel->addWidget(modelRbX);
	hLayoutModel->addWidget(modelRbY);
	hLayoutModel->addWidget(modelRbZ);
	hLayoutModel->addWidget(modelSeekBar);
	hLayoutModel->setAlignment(Qt::AlignTop | Qt::AlignVCenter);

	QHBoxLayout* hLayoutView = new QHBoxLayout(this);
	QRadioButton* viewRbX = new QRadioButton(this);
	viewRbX->setText("X");
	QRadioButton* viewRbY = new QRadioButton(this);
	viewRbY->setText("Y");
	QRadioButton* viewRbZ = new QRadioButton(this);
	viewRbZ->setText("Z");
	SeekBarTipsWidget* viewSeekBar = new SeekBarTipsWidget(this);
	//此处的value需要转换为-1~1之间
	viewSeekBar->initContent(-100, 100, 5, "View矩阵参数调整",
		[=](int value) {
			switch (mTranslateType) {
			case 0://x
				mTranslateX = value / 100.0f;
				break;//y
			case 1:
				mTranslateY = value / 100.0f;
				break;
			case 2://z
				mTranslateZ = value / 100.0f;
				break;
			}
			qDebug()
				<< "mTranslateX=" << mTranslateX
				<< ",mTranslateY=" << mTranslateY
				<< "mTranslateZ=" << mTranslateZ;
			uViewMatrix.translate(QVector3D(mTranslateX, mTranslateY, mTranslateZ));//设置view矩阵（Z轴平移）
			update();
		});
	connect(viewRbX, &QPushButton::clicked, [this]() {
		mTranslateType = 0;
		});
	connect(viewRbY, &QPushButton::clicked, [this]() {
		mTranslateType = 1;
		});
	connect(viewRbZ, &QPushButton::clicked, [this]() {
		mTranslateType = 2;
		});
	hLayoutView->addWidget(viewRbX);
	hLayoutView->addWidget(viewRbY);
	hLayoutView->addWidget(viewRbZ);
	hLayoutView->addWidget(viewSeekBar);

	QHBoxLayout* hLayoutProjection = new QHBoxLayout(this);
	QRadioButton* projectionRbX = new QRadioButton(this);
	projectionRbX->setText("X");
	QRadioButton* projectionRbY = new QRadioButton(this);
	projectionRbY->setText("Y");
	QRadioButton* projectionRbZ = new QRadioButton(this);
	projectionRbZ->setText("Z");
	SeekBarTipsWidget* projectionSeekBar = new SeekBarTipsWidget(this);
	//此处的value需要转换为-1~1之间
	projectionSeekBar->initContent(-45, 45, 1, "projection矩阵参数调整",
		[=](int value) {
			mPerspectiveAngle = float(value);
			qDebug() << "mPerspectiveAngle=" << mPerspectiveAngle;
			uProjectionMatrix.perspective(mPerspectiveAngle, 480.0f / 480.0f, 0.1f, 100.0f);
			update();
		});
	connect(projectionRbX, &QPushButton::clicked, [this]() {
		mTranslateType = 0;
		});
	connect(projectionRbY, &QPushButton::clicked, [this]() {
		mTranslateType = 1;
		});
	connect(projectionRbZ, &QPushButton::clicked, [this]() {
		mTranslateType = 2;
		});
	hLayoutProjection->addWidget(projectionRbX);
	hLayoutProjection->addWidget(projectionRbY);
	hLayoutProjection->addWidget(projectionRbZ);
	hLayoutProjection->addWidget(projectionSeekBar);

	vBoxLayout->addLayout(hLayoutModel);
	vBoxLayout->addLayout(hLayoutView);
	vBoxLayout->addLayout(hLayoutProjection);
	vBoxLayout->setAlignment(Qt::AlignTop);

	QTimer* timer = new QTimer(this);
	//connect(btnRed, &QPushButton::clicked, [this]() {
	//	uModelMatrix.setToIdentity();
	//	uViewMatrix.setToIdentity();
	//	uProjectionMatrix.setToIdentity();
	//	uModelMatrix.rotate(-55.0f, QVector3D(0.5f, 1.0f, 0.0f));//设置model矩阵（旋转）
	//	uViewMatrix.translate(QVector3D(0.0f, 0.0f, -3.0f));//设置view矩阵（Z轴平移）
	//	uProjectionMatrix.perspective(45.0f, 480.0f / 480.0f, 0.1f, 100.0f);//透视投影
	//	update();
	//	});

	/*connect(btnGreen, &QPushButton::clicked, [=]() {
		if (mScaleIndex > 3) {
			mScaleIndex = 0;
		}
		setTextureScale();
		mScaleIndex++;
		});

	connect(btnFlipX, &QPushButton::clicked, [=]() {
		timer->start(50);
		});

	connect(timer, &QTimer::timeout, [this] {
		if (mRoate > 360) {
			mRoate = 0;
		}
		setTextureRoate();
		mRoate += 10;
		});*/
}
void GLTextureMVP3DWindow::initializeGL() {
	this->initializeOpenGLFunctions();
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glEnable(GL_DEPTH_TEST);//启用深度测试
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	//3D坐标总共有36个点，6个面
	float vertices[] = {
			-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
			 0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
			 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
			 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
			-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
			-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

			-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
			 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
			 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
			 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
			-0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
			-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

			-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
			-0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
			-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
			-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
			-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
			-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

			 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
			 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
			 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
			 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
			 0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
			 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

			-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
			 0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
			 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
			 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
			-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
			-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

			-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
			 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
			 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
			 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
			-0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
			-0.5f,  0.5f, -0.5f,  0.0f, 1.0f
	};

	//创建VAO
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);
	glBindVertexArray(VAO);

	//创建VBO
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	//告知显卡如何解析顶点数据
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);

	//解绑VBO
	//glBindBuffer(GL_ARRAY_BUFFER, 0);

	stbi_set_flip_vertically_on_load(true);
	texture = buildTexture("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/images/cz.jpeg",
		GL_RGB);

	//小程序
	programId = buildAttachShaderAndReturnProgramId(":/QtForOpenCV4Tool/shader/texture_mvp_first_3d.vert",
		":/QtForOpenCV4Tool/shader/texture_mvp_first_3d.frag");

	uModelMatrix.setToIdentity();
	uViewMatrix.setToIdentity();
	uProjectionMatrix.setToIdentity();
	uModelMatrix.rotate(-55.0f, QVector3D(0.5f, 1.0f, 0.0f));//设置model矩阵（旋转）
	uViewMatrix.translate(0.0f, 0.0f, -3.0f);//设置view矩阵（Z轴平移）
	uProjectionMatrix.perspective(45.0f, 480.0f / 480.0f, 0.1f, 100.0f);//透视投影
}
void GLTextureMVP3DWindow::resizeGL(int w, int h) {
	glViewport(0, 0, w, h);
}
void GLTextureMVP3DWindow::paintGL() {
	glBindVertexArray(VAO);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture);
	glUseProgram(programId);
	GLint ourTextureLocation = glGetUniformLocation(programId, "ourTexture");
	glUniform1i(ourTextureLocation, 0);
	for (int i = 0;i < 5;i++) {
		/*uViewMatrix.setToIdentity();
		uModelMatrix.setToIdentity();
		uProjectionMatrix.setToIdentity();*/
		glUniformMatrix4fv(glGetUniformLocation(programId, "uModel"), 1, false, uModelMatrix.data());
		uViewMatrix.translate(cubePositions[i]);//设置view矩阵（Z轴平移）
		glUniformMatrix4fv(glGetUniformLocation(programId, "uView"), 1, false, uViewMatrix.data());
		glUniformMatrix4fv(glGetUniformLocation(programId, "uProjection"), 1, false, uProjectionMatrix.data());
		glDrawArrays(GL_TRIANGLES, 0, 36);
	}
}
GLuint GLTextureMVP3DWindow::buildTexture(QString textureFileName, GLint imageColorType) {
	GLuint mTexture;
	////创建纹理
	glGenTextures(1, &mTexture);
	glBindTexture(GL_TEXTURE_2D, mTexture);
	//设置纹理环绕方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//设置纹理过滤方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	//生成纹理
	int width, height, mChannels;
	//QString path = getTexturePath(textureFileName);
	//qDebug() << path.toStdString().c_str();
	unsigned char* data = stbi_load(textureFileName.toStdString().c_str(), &width, &height, &mChannels, 0);
	if (data) {
		qDebug() << "图片加载成功,width=" << width << ",height=" << height;
		glTexImage2D(GL_TEXTURE_2D, 0, imageColorType, width, height, 0, imageColorType, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else {
		qDebug() << "图像数据加载失败";
	}
	stbi_image_free(data);
	return mTexture;
}

GLTextureMVP3DWindow::~GLTextureMVP3DWindow()
{
}
